#include "mainwindow.h"
#include <QTextStream>
#include "./ui_mainwindow.h"
#define CONFIG_FILE "config/config.json"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent), ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    QApplication::setOverrideCursor(Qt::BlankCursor);
    updatePermission("0");                                                                        // 默认无权限
    ui_init();                                                                                    // 初始化显示ui
    config_init(CONFIG_FILE);                                                                     // 初始化加载配置json
    plugin_init(QCoreApplication::applicationDirPath() + "/plugin", &MainWindow::handlePluginUI); // 加载所有插件，并且将所有插件的widget创建后传递给槽函数handlePluginUI

    // 在创建 LoginDialog 后连接信号
    // 创建 login 控件并放入布局
    if (!mLogin)
    {
        mLogin = new LoginDialog(this);
    }
    connect(mLogin, &LoginDialog::loginStatusChanged, this, [=](bool isLoggedIn)
            {
        // QString iconName = QFileInfo("./icon/设置.png").fileName();
        // display_widget->setMenuWidgetVisibleByName(iconName, isLoggedIn);
        if (isLoggedIn) {
            qDebug() << "用户已登录";
            updatePermission("1");

        } else {
            qDebug() << "用户已登出";
            updatePermission("0");
        }

        IPlugin *plugin_config_t = m_manager.getPlugin("plugin_config");
        plugin_config_t->sendMessageToPlugin(configJson);
        IPlugin *plugin_event_record_t = m_manager.getPlugin("plugin_eventrecord");
        plugin_event_record_t->sendMessageToPlugin(configJson);
        IPlugin *plugin_output_t = m_manager.getPlugin("plugin_output");
        plugin_output_t->sendMessageToPlugin(configJson); });
}

MainWindow::~MainWindow()
{
    delete ui;
}

/**
 * @brief MainWindow::ui_init ui初始化
 */
void MainWindow::ui_init()
{
    setWindowFlags(windowFlags() | Qt::FramelessWindowHint);
    // 获取屏幕尺寸并设置全屏
    //  QScreen *screen = QGuiApplication::primaryScreen();
    setFixedSize({1024, 600});
    show();

    // 默认显示启动页
    ui->stackedWidget->setCurrentWidget(ui->start_widget);

    // ui->label_logo->setPixmap(QPixmap("./icon/logo_blue.png")
    //                               .scaled(48, 48, Qt::KeepAspectRatio, Qt::SmoothTransformation));
    // ui->label_logo->setFixedSize(48, 48);
    ui->pb_login->setFlat(true); // 透明背景
    QPixmap pix("./icon/login.png");
    ui->pb_login->setIcon(pix.scaled(32, 32, Qt::KeepAspectRatio, Qt::SmoothTransformation));
    ui->pb_login->setIconSize(QSize(32, 32));

    /*将显示界面布局*/
    display_widget = new displaywidget(ui->widget_display);
    QVBoxLayout *layout = new QVBoxLayout(ui->widget_display);
    layout->setContentsMargins(0, 0, 0, 0);
    layout->setSpacing(0);
    layout->addWidget(display_widget);

    display_widget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

    // 创建定时器
    QTimer *timer = new QTimer(this);

    // 定义更新日期和时间的槽函数
    QObject::connect(timer, &QTimer::timeout, [&]()
                     {
                         QDateTime currentDateTime = QDateTime::currentDateTime();
                         ui->label_date->setText(currentDateTime.date().toString("yyyy-MM-dd"));
                         ui->label_time->setText(currentDateTime.time().toString("hh:mm:ss")); });

    // 启动定时器，每秒更新一次
    timer->start(1000);

    display_widget->initializeUI(UI_H_MENU);

    // timer_data = new QTimer(this);

    // // 连接 timeout() 信号到槽函数
    // connect(timer_data, &QTimer::timeout, this, &MainWindow::onTimeout);
}

/**
 * @brief MainWindow::config_init
 * @param path
 * @return 返回转换成QString的配置json文件
 */
void MainWindow::config_init(QString path)
{
    QFile file(path);
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        qWarning() << "无法打开文件:" << file.errorString();
    }

    QTextStream stream(&file);
    // stream.setEncoding(QStringConverter::Utf8); // 确保UTF8编码
    configJson = stream.readAll();
    // 将 JSON 字符串解析为 QJsonDocument
    QJsonDocument doc = QJsonDocument::fromJson(configJson.toUtf8());

    if (!doc.isNull() && doc.isObject())
    {
        // 获取根对象
        QJsonObject rootObject = doc.object();

        // 获取 plugin_config 对象
        if (rootObject.contains("plugin_config") && rootObject["plugin_config"].isObject())
        {
            QJsonObject pluginConfig = rootObject["plugin_config"].toObject();

            // 提取 tittle 字段
            if (pluginConfig.contains("tittle"))
            {
                QString title = pluginConfig["tittle"].toString();
                ui->label_tittle->setText(title);
                qDebug() << "Title from config.json:" << title;
            }
            else
            {
                qDebug() << "tittle field not found in plugin_config";
            }
        }
        else
        {
            qDebug() << "plugin_config object not found";
        }
    }
    else
    {
        qDebug() << "Invalid JSON format";
    }

    file.close();
}
void MainWindow::saveJsonToFile(const QString &jsonString, const QString &filePath)
{
    // 解析 JSON 字符串
    QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonString.toUtf8());
    if (jsonDoc.isNull())
    {
        qDebug() << "JSON 解析失败";
        return;
    }

    // 写入文件
    QFile file(filePath);
    if (file.open(QIODevice::WriteOnly))
    {
        file.write(jsonDoc.toJson());
        file.close();
        qDebug() << "JSON 文件保存成功：" << filePath;
    }
    else
    {
        qDebug() << "文件打开失败";
    }
}

void MainWindow::updatePermission(const QString &newPermission)
{
    // 打开文件
    QFile file(CONFIG_FILE);
    if (!file.open(QFile::ReadWrite))
    {
        qDebug() << "无法打开文件：" << CONFIG_FILE;
        return;
    }

    // 读取文件内容
    QByteArray data = file.readAll();
    QJsonDocument doc = QJsonDocument::fromJson(data);

    if (doc.isNull())
    {
        qDebug() << "解析 JSON 失败";
        file.close();
        return;
    }

    // 修改 permission 字段
    QJsonObject rootObj = doc.object();
    QJsonObject pluginConfig = rootObj.value("plugin_config").toObject();
    pluginConfig["permission"] = newPermission; // 修改 permission
    rootObj["plugin_config"] = pluginConfig;
    doc.setObject(rootObj);

    file.resize(0); // 清空旧内容
    // 将修改后的内容写回文件
    file.seek(0);
    file.write(doc.toJson(QJsonDocument::Indented));
    file.close();

    qDebug() << "permission 已更新为：" << newPermission;
    config_init(CONFIG_FILE); // 更新加载json
}
/**
 * @brief MainWindow::plugin_init 插件初始化
 * @param path
 */
void MainWindow::plugin_init(QString path, void (MainWindow::*PluginUI_load_slot)(QString, QWidget *))
{
    QString exeDirPath = QCoreApplication::applicationDirPath();
    QDir dir(exeDirPath);
    QStringList filters = {"*.dll", "*.so", "*.dylib"};
    QFileInfoList files = dir.entryInfoList(filters, QDir::Files);

    QSet<QString> uniqueNames;
    for (const QFileInfo &file : files)
    {
        // 只加载文件名中包含"plugin"的动态库
        if (file.baseName().contains("plugin"))
        {
            uniqueNames.insert(file.baseName());
        }
    }
    pluginSize = uniqueNames.size();

    // 绑定插件信号,当插件被加载,执行ui加载程序
    connect(&m_manager, &PluginManager::pluginLoaded, this, PluginUI_load_slot);

    m_manager.loadAll(exeDirPath);
    // qDebug() << "plugin load path:"<< exeDirPath + "/plugin";
}
/**
 * @brief MainWindow::restartApplication 重启应用程序
 */
void MainWindow::restartApplication()
{
    qApp->quit();
    QProcess::startDetached(qApp->arguments()[0], qApp->arguments().mid(1));
}
/**
 * @brief MainWindow::handlePluginMessage 解析来自所有插件的信息
 * @param msg
 */
void MainWindow::handlePluginMessage(QString pluginName, QString msg)
{
    // qDebug() << "comfrom plugin:" << pluginName << " txt:" << msg;
    // 插件ui投出的信息
    // 众电主页
    if (pluginName.contains("datablock"))
    {
        /*切换主页到数据库页，并切换到实时数据，自动选择投过来的msg里的柜子*/
        qDebug() << "comfrom plugin:" << pluginName << " txt:" << msg;
        // 要求数据库表刷新
        IPlugin *plugin_database_t = m_manager.getPlugin("plugin_database");
        plugin_database_t->sendMessageToPlugin(msg); // 将柜名发进去
        QString iconName = QFileInfo("./icon/详细.png").fileName();
        display_widget->switchToPageByIconName(iconName);
    }
    // 输出模块
    else if (pluginName.contains("output"))
    {
        // 在这里处理来自 plugin_output 插件的消息
        qDebug() << "来自输出插件的消息:" << pluginName << " 内容:" << msg;
        // 可以在这里添加特定的处理逻辑
    }
    else if (pluginName.contains("eventrecord"))
    {
        // 在这里处理来自 plugin_eventrecord 插件的消息
        qDebug() << "来自事件记录插件的消息:" << pluginName << " 内容:" << msg;
        // 可以在这里添加特定的处理逻辑
        if (msg.contains("EventRecord cleared"))
        {
            IPlugin *plugin_warn_t = m_manager.getPlugin("plugin_warn");
            plugin_warn_t->sendMessageToPlugin(msg);
        }
    }
    // 配置页
    if (pluginName.contains("config") || pluginName.contains("output"))
    {
        // 收到配置更新指令
        if (msg.contains("updated"))
        {
            QTimer::singleShot(2000, this, &MainWindow::restartApplication);
        }
    }

    if (pluginName.contains("modbus"))
    {
        if (msg.contains("plugin_data"))
        {
            IPlugin *plugin_datablock_t = m_manager.getPlugin("plugin_datablock");
            plugin_datablock_t->sendMessageToPlugin(msg);
            IPlugin *plugin_database_t = m_manager.getPlugin("plugin_database");
            plugin_database_t->sendMessageToPlugin(msg);
            IPlugin *plugin_warn_t = m_manager.getPlugin("plugin_warn");
            plugin_warn_t->sendMessageToPlugin(msg);
            IPlugin *plugin_output_t = m_manager.getPlugin("plugin_output");
            plugin_output_t->sendMessageToPlugin(msg);
        }
    }
    if (pluginName.contains("warn"))
    {
        if (msg.startsWith("warningTableSumChanged:"))
        {
            QString countStr = msg.mid(QString("warningTableSumChanged:").length());
            bool ok;
            int warningCount = countStr.toInt(&ok);
            if (ok)
            {
                // 成功解析出报警数量
                QString countText = QString::number(warningCount);
                // 使用 countText 更新UI或其他处理
                // qDebug() << "报警数量:" << warningCount;
                QString iconName = QFileInfo("./icon/报警.png").fileName();
                display_widget->updateAlarmButtonText(iconName, countText);
            }
        }
    }
}

/**
 * @brief MainWindow::handlePluginUI 所有插件ui加载程序,将ui放到合适的地方
 * @param name
 * @param plugin_ui
 */
void MainWindow::handlePluginUI(QString pluginName, QWidget *plugin_ui)
{
    // 插件ui放到显示页，但此时仍然是显示进度条的
    // 众电主页
    if (pluginName.contains("datablock"))
    {
        // 连接插件信号到主窗口,这里只取了一个插件,并绑定了主界面,也可以绑定其他ui的接收消息槽函数
        IPlugin *plugin_datablock_t = m_manager.getPlugin(pluginName);
        connect(plugin_datablock_t, &IPlugin::messageFromPlugin, this, &MainWindow::handlePluginMessage);
        display_widget->insert_project_menuWidget("./icon/主页总览.png", plugin_ui);
    }
    // 输出模块
    else if (pluginName.contains("output"))
    {
        // 连接插件信号到主窗口
        IPlugin *plugin_output_t = m_manager.getPlugin(pluginName);
        connect(plugin_output_t, &IPlugin::messageFromPlugin, this, &MainWindow::handlePluginMessage);
        // 根据需要决定如何显示输出插件的UI
        display_widget->insert_project_menuWidget("./icon/系统设置.png", plugin_ui); // 需要准备相应的图标
    }
    // 配置页
    if (pluginName.contains("config"))
    {
        // 连接插件信号到主窗口,这里只取了一个插件,并绑定了主界面,也可以绑定其他ui的接收消息槽函数
        IPlugin *plugin_config_t = m_manager.getPlugin(pluginName);
        connect(plugin_config_t, &IPlugin::messageFromPlugin, this, &MainWindow::handlePluginMessage);
        display_widget->insert_project_menuWidget("./icon/设备设置.png", plugin_ui);
        // QString iconName = QFileInfo("./icon/设置.png").fileName();
        // display_widget->setMenuWidgetVisibleByName(iconName, false);
    }

    // 数据库页
    if (pluginName.contains("database"))
    {
        // 连接插件信号到主窗口,这里只取了一个插件,并绑定了主界面,也可以绑定其他ui的接收消息槽函数
        IPlugin *plugin_database_t = m_manager.getPlugin(pluginName);
        connect(plugin_database_t, &IPlugin::messageFromPlugin, this, &MainWindow::handlePluginMessage);
        display_widget->insert_project_menuWidget("./icon/详细.png", plugin_ui);
        QString iconName = QFileInfo("./icon/详细.png").fileName();
        display_widget->setMenuWidgetVisibleByName(iconName, false); // 数据库变成详情页，不再允许直接按钮进入
    }

    // modbus采集模块
    if (pluginName.contains("modbus"))
    {
        // 连接插件信号到主窗口,这里只取了一个插件,并绑定了主界面,也可以绑定其他ui的接收消息槽函数
        IPlugin *plugin_modbus_t = m_manager.getPlugin(pluginName);
        connect(plugin_modbus_t, &IPlugin::messageFromPlugin, this, &MainWindow::handlePluginMessage);
        // display_widget->insert_project_menuWidget("./icon/详细.png", plugin_ui);
    }
    // 警告模块
    if (pluginName.contains("warn"))
    {
        // 连接插件信号到主窗口,这里只取了一个插件,并绑定了主界面,也可以绑定其他ui的接收消息槽函数
        IPlugin *plugin_modbus_t = m_manager.getPlugin(pluginName);
        connect(plugin_modbus_t, &IPlugin::messageFromPlugin, this, &MainWindow::handlePluginMessage);

        display_widget->insertAlarmButton("./icon/报警.png", plugin_ui, "0");
        // QString iconName = QFileInfo("./icon/报警.png").fileName();
        // display_widget->setMenuWidgetVisibleByName(iconName, false);
    }
    // 事件记录模块
    if (pluginName.contains("eventrecord"))
    {
        // 连接插件信号到主窗口
        IPlugin *plugin_eventrecord_t = m_manager.getPlugin(pluginName);
        connect(plugin_eventrecord_t, &IPlugin::messageFromPlugin, this, &MainWindow::handlePluginMessage);

        // 根据需要决定如何显示事件记录插件的UI
        display_widget->insert_project_menuWidget("./icon/事件记录.png", plugin_ui); // 需要准备相应的图标
    }
    // 进度条ui
    load_cnt++;
    QString load_name = QString("loading plugin :%1 success !!! plugin load size (%2/%3)").arg(pluginName).arg(load_cnt).arg(pluginSize);
    qDebug() << load_name;

    ui->progressBar->setValue(100 / pluginSize * load_cnt);
    ui->textBrowser->append(load_name);
    ui->label->setText(load_name);

    if (load_cnt == pluginSize)
    {
        // 初始化的时候，需要显示东西，而不是直到获取到配置ui
        IPlugin *plugin_datablock_t = m_manager.getPlugin("plugin_datablock");
        plugin_datablock_t->sendMessageToPlugin(configJson);
        IPlugin *plugin_config_t = m_manager.getPlugin("plugin_config");
        plugin_config_t->sendMessageToPlugin(configJson);
        IPlugin *plugin_database_t = m_manager.getPlugin("plugin_database");
        plugin_database_t->sendMessageToPlugin(configJson);
        IPlugin *plugin_modbus_t = m_manager.getPlugin("plugin_modbus");
        plugin_modbus_t->sendMessageToPlugin(configJson);
        IPlugin *plugin_output_t = m_manager.getPlugin("plugin_output");
        plugin_output_t->sendMessageToPlugin(configJson);
        IPlugin *plugin_event_t = m_manager.getPlugin("plugin_eventrecord");
        plugin_event_t->sendMessageToPlugin(configJson);
        QTimer::singleShot(1000, this, [=]() { // 1s后再跳转，为了可以肉眼见到信息被加载
            stackWidget = ui->stackedWidget;
            stackWidget->setAnimationDuration(500);

            stackWidget->changeCurrentWidget(ui->main_widget);
            QString iconName = QFileInfo("./icon/主页总览.png").fileName();
            display_widget->switchToPageByIconName(iconName);
        });

        // 设置定时器间隔为 1000 毫秒（1 秒）
        // timer_data->start(3000); // 开始刷新json的数据内容
    }
}

// 热升级插件
//  void MainWindow::onHotSwapClicked() {
//      QString newPath = QFileDialog::getExistingDirectory(this, "选择新插件路径");
//      if(!newPath.isEmpty()) {
//          foreach(QString name, m_manager.loadedPlugins()) {
//              m_manager.unloadPlugin(name);
//          }
//          m_manager.loadAll(newPath);
//      }
//  }

void MainWindow::on_pb_login_released()
{
    // 显示模态对话框（阻塞主线程）
    mLogin->show();
    // QMessageBox::information(this, "提示", "请先完成登录");
}
